#include "Sock.hpp"
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fstream>

//其中wwwroot 就叫做web根目录，wwwroot目录下防止的内容，都叫做资源！！
// wwwroot目录下的index.html就叫做网站的首页

#define WWWROOT "./wwwroot/"
#define HOME_PAGE "index.html"

void Usage(std::string proc)
{
    std::cout << "Usage: " << proc << " port" << std::endl;
}

//验证GET 和 POST方法
void *HandlerHttpRequest(void *args)
{
    // Http协议，如果自己写的话，本质是，我们要根据协议内容，来进行文本分析！

    int sock = *(int *)args;
    delete (int *)args;
    pthread_detach(pthread_self());

#define SIZE 2048 * 10

    char buffer[SIZE];
    memset(buffer, 0, sizeof(buffer));

    // 这种读法是不正确的，只不过在现在没有被暴露出来罢了
    ssize_t s = recv(sock, buffer, sizeof(buffer), 0);
    if (s > 0)
    {
        buffer[s] = 0;
        std::cout << buffer; //查看http的请求格式! for test
        

        // std::string response = "http/1.1 301 Permanently moved\n";
        // std::string response = "http/1.1 302  Found\n";
        // response += "Location: https://www.qq.com/\n";
        // response += "\n";
        // send(sock, response.c_str(), response.size(), 0);


        // http协议处理，本质是文本分析
        //所谓的文本分析
        //  1. http协议本身的字段
        //  2. 提取参数，如果有的话
        // GET 或者 POST 其实是前后端交互的一个重要方式

        // std::string http_response = "http/1.0 200 OK\n";
        // http_response += "Content-Type: text/plain\n"; //text/plain,正文是普通的文本
        // http_response += "\n"; //传说中的空行
        // http_response += "hello bit, hello 102!";
        // send(sock, http_response.c_str(), http_response.size(), 0); //ok??
        // if(method == '/') path = "./wwwroot/index.html"

        std::string html_file = WWWROOT;
        html_file += HOME_PAGE;

        //接下来，才是正文
        std::ifstream in(html_file);
        if (!in.is_open())
        {
             std::string http_response = "http/1.0 404 NOT FOUND\n";
            // 正文部分的数据类型
            http_response += "Content-Type: text/html; charset=utf8\n";
            http_response += "\n";
            http_response += "<html><p>你访问的资源不存在</p></html>";
            send(sock, http_response.c_str(), http_response.size(), 0);
        }
        else
        {
            // std::cout << "read html begin" << std::endl;
            struct stat st;
            stat(html_file.c_str(), &st);
            // 返回的时候，不仅仅是返回正文网页信息，而是还要包括http的请求
            std::string http_response = "http/1.0 200 ok\n";
            // 正文部分的数据类型
            http_response += "Content-Type: text/html; charset=utf8\n";
            http_response += "Content-Length: ";
            http_response += std::to_string(st.st_size);
            http_response += "\n";

            //Set-Cookie: 服务器向浏览器设置一个cookeie
            //user password
            //open, write,close name
            //name -> sessin id ->Set-Cookie
            http_response += "Set-Cookie: id=11111\n";
            http_response += "Set-Cookie: password=2222\n";
            http_response += "\n";
            std::string content;
            std::string line;
            while (std::getline(in, line))
            {
                content += line;
            }
            http_response += content;
            in.close();

            // std::cout << http_response << std::endl;

            send(sock, http_response.c_str(), http_response.size(), 0);

            // std::cout << "read html end" << std::endl;
        }
    }

    close(sock);
    return nullptr;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }

    uint16_t port = atoi(argv[1]);
    int listen_sock = Sock::Socket();
    Sock::Bind(listen_sock, port);
    Sock::Listen(listen_sock);

    for (;;)
    {
        int sock = Sock::Accept(listen_sock);
        if (sock > 0)
        {
            pthread_t tid;
            int *parm = new int(sock);
            pthread_create(&tid, nullptr, HandlerHttpRequest, parm);
        }
    }
}
